# -*- coding: utf-8 -*-
from datetime import datetime
from hashlib import md5

from flask import render_template, flash, redirect, url_for, g, request

from flask.ext.login import current_user, login_user, login_required, logout_user

from app import app, lm, db
from forms import LoginForm, EditUserForm, SignInForm, PostForm, SearchForm
from models import User, Post
from config import POSTS_PER_PAGE, MAX_SEARCH_RESULTS
from emails import follower_notification

__author__ = 'nibo'


@lm.user_loader
def load_user(pid):
    return User.query.get(int(pid))


@app.before_request
def defore_request():
    g.user = current_user
    if g.user.is_authenticated():
        # 更新用户最后登录时间
        g.user.last_seen = datetime.utcnow()
        db.session.add(g.user)
        db.session.commit()
        g.search_form = SearchForm()


@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
@app.route('/index/<int:page>', methods=['GET', 'POST'])
@login_required
def index(page=1):
    """
    首页
    :return:
    """
    u = g.user
    form = PostForm()
    if form.validate_on_submit():
        post = Post(body=form.post.data, timestamp=datetime.utcnow(), author=g.user)
        db.session.add(post)
        db.session.commit()
        flash(u'微博发布成功！')
        return redirect(url_for('index'))
    posts = g.user.followed_posts().paginate(page, POSTS_PER_PAGE, False)
    return render_template('index.html', title=u'首页', user=u, posts=posts, form=form)


@app.route('/login', methods=['GET', 'POST'])
def login():
    """
    用户登录
    :return:
    """
    if g.user and g.user.is_authenticated():
        return redirect(url_for('index'))
    form = LoginForm()
    if form.validate_on_submit():
        u = User.query.filter_by(email=form.email.data,
                                 password=md5(form.email.data + form.password.data)
                                 .hexdigest()).first()
        if u is None:
            flash(u'用户名或密码错误！')
            return redirect(url_for('login'))
        else:
            login_user(u, remember=form.remember_me.data)
            return redirect(request.args.get('next') or url_for('index'))
    return render_template('login.html', form=form)


@app.route('/signin', methods=['GET', 'POST'])
def signin():
    """
    用户注册
    :return:
    """
    form = SignInForm()
    if form.validate_on_submit():
        u = User(nickname=form.nickname.data, email=form.email.data,
                 password=md5(form.email.data + form.password.data).hexdigest())
        db.session.add(u)
        # 用户注册的同时即关注自身
        u.follow(u)
        db.session.add(u)
        db.session.commit()
        flash(u'注册成功，请登录！')
        return redirect(url_for('login'))
    return render_template('signin.html', form=form)


@app.route('/logout')
def logout():
    """
    退出
    :return:
    """
    logout_user()
    return redirect(url_for('login'))


@app.route('/user/<nickname>')
@app.route('/user/<nickname>/<int:page>')
@login_required
def user(nickname, page=1):
    """
    用户个人主页
    :param nickname: 昵称
    :return:
    """
    u = User.query.filter_by(nickname=nickname).first()
    if u is None:
        flash(u'用户不存在：%s！' % nickname)
        return redirect(url_for('index'))

    posts = u.posts.paginate(page, POSTS_PER_PAGE, False)
    return render_template('user.html', user=u, posts=posts)


@app.route('/edit', methods=['GET', 'POST'])
@login_required
def edit():
    """
    编辑个人信息
    :return:
    """
    form = EditUserForm(g.user.nickname)
    if form.validate_on_submit():
        g.user.nickname = form.nickname.data
        g.user.about_me = form.about_me.data
        db.session.add(g.user)
        db.session.commit()
        flash(u'个人资料保存成功')
        return redirect(url_for('edit'))
    return render_template('edit.html', form=form)


@app.route('/follow/<nickname>')
@login_required
def follow(nickname):
    """
    关注
    :param nickname: 昵称
    :return:
    """
    user_info = User.query.filter_by(nickname=nickname).first()
    if user_info is None:
        flash(u'用户"%s"不存在！' % nickname)
        return redirect(url_for('index'))
    if user_info == g.user:
        flash(u'不能关注自己！')
        return redirect(url_for('user', nickname=nickname))
    u = g.user.follow(user_info)
    if u is None:
        flash(u'不能关注用户"%s"！' % nickname)
        return redirect(url_for('user', nickname=nickname))
    db.session.add(u)
    db.session.commit()
    flash(u'关注用户"%s"成功！' % nickname)
    follower_notification(user_info, g.user)
    return redirect(url_for('user', nickname=nickname))


@app.route('/unfollow/<nickname>')
@login_required
def unfollow(nickname):
    """
    取消关注
    :param nickname: 昵称
    :return:
    """
    user_info = User.query.filter_by(nickname=nickname).first()
    if user_info is None:
        flash(u'用户"%s"不存在！' % nickname)
        return redirect(url_for('index'))
    if user_info == g.user:
        flash(u'不能对自己取消关注！')
        return redirect(url_for('user', nickname=nickname))
    u = g.user.unfollow(user_info)
    if u is None:
        flash(u'不能对用户"%s"取消关注！' % nickname)
        return redirect(url_for('user', nickname=nickname))
    db.session.add(u)
    db.session.commit()
    flash(u'已取消对用户"%s"的关注！' % nickname)
    return redirect(url_for('user', nickname=nickname))


@app.route('/search', methods=['POST'])
def search():
    if not g.search_form.validate_on_submit():
        return redirect(url_for('index'))

    return redirect(url_for('search_results', query=g.search_form.search.data))


@app.route('/search_results/<query>')
def search_results(query):
    results = Post.query.whoosh_search(query, MAX_SEARCH_RESULTS).all()
    return render_template('search_results.html', query=query, results=results)


@app.errorhandler(404)
def internal_error(error):
    """
    404错误页面处理
    :param error:
    :return:
    """
    return render_template('404.html')


@app.errorhandler(500)
def internal_error(error):
    """
    500错误页面处理
    :param error:
    :return:
    """
    db.session.rollback()
    return render_template('500.html')
